ICE Store - Plataforma de venda de jogos¶
Parte 1 - Importação de Dados e Preparação dos Dados:¶
# Importando bibliotecas
import pandas as pd
import plotly.express as px
from scipy import stats as st
import plotly.io as pio
pio.renderers.default = "notebook"
# Lendo o dataset
games = pd.read_csv('../data/games.csv')
# Exibindo informações do dataset
games.info()
<class 'pandas.DataFrame'> RangeIndex: 16715 entries, 0 to 16714 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Name 16713 non-null str 1 Platform 16715 non-null str 2 Year_of_Release 16446 non-null float64 3 Genre 16713 non-null str 4 NA_sales 16715 non-null float64 5 EU_sales 16715 non-null float64 6 JP_sales 16715 non-null float64 7 Other_sales 16715 non-null float64 8 Critic_Score 8137 non-null float64 9 User_Score 10014 non-null str 10 Rating 9949 non-null str dtypes: float64(6), str(5) memory usage: 1.4 MB
Na nossa tabela encontramos diversos valores ausentes, alguns deles podendo ter sido gerados por erros de armazenamento no banco de dados, como também por falta de informações que poderiam estar em processo de levantamento (atualização), como as notas dos usuários de jogos vendidos recentemente.
- A coluna "user_score", possui dados ausentes e dados nomeados como "tbd" ou "To be determined", e com isso nossa coluna possui dados do tipo object, para nossa análise precisamos que ela se apresente com tipo float, realizaremos a conversão dos dados, utilizando o parâmetro errors='coerce' da função pd.to_numeric(). Com isso todos os valores 'tbd' se tornam NaN, se houver algum valor numérico em string por exemplo: '7.5' será convertido normalmente para float64, os NaN se manterão os mesmo e nossos valores númericos datados como object passarão a float64.
# Passando o nome das colunas para o padrão snake_case (todas as letras minúsculas e separadas por underline)
# criando uma lista vazia para os novos nomes
new_columns = []
# pequeno ciclo para acessar os nomes das colunas
for old_names in games.columns:
# convertendo as colunas do dateset com o método lower()
name_lowered = old_names.lower()
# atribuindo os nomes minúsculos a nossa lista "new_columns"
new_columns.append(name_lowered)
# atribuindo a lista com os novos nomes as colunas do Dataset.
games.columns = new_columns
# imprindo as informações do dataset atualizado
print(games.info())
<class 'pandas.DataFrame'> RangeIndex: 16715 entries, 0 to 16714 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 name 16713 non-null str 1 platform 16715 non-null str 2 year_of_release 16446 non-null float64 3 genre 16713 non-null str 4 na_sales 16715 non-null float64 5 eu_sales 16715 non-null float64 6 jp_sales 16715 non-null float64 7 other_sales 16715 non-null float64 8 critic_score 8137 non-null float64 9 user_score 10014 non-null str 10 rating 9949 non-null str dtypes: float64(6), str(5) memory usage: 1.4 MB None
# Verificando dados ausentes na tabela
ausentes = games.isna().sum()
ausentes
name 2 platform 0 year_of_release 269 genre 2 na_sales 0 eu_sales 0 jp_sales 0 other_sales 0 critic_score 8578 user_score 6701 rating 6766 dtype: int64
# Corrigindo dados ausentes na coluna "name"
# criando uma máscara para os dados ausentes na coluna "name"
miss_names = ~games['name'].isna()
# filtrando a coluna com os dados não ausentes
games_filtered = games[miss_names]
# Removendo dados ausentes da coluna "year_of_release"
# criando uma máscara para os dados ausentes na coluna "year_of_release"
games_years = ~games_filtered['year_of_release'].isna()
# filtrando a coluna com os dados não ausentes
games_filtered = games_filtered[games_years].copy()
# convertendo a coluna "year_of_release" para o Dtype - int
games_filtered['year_of_release'] = games_filtered['year_of_release'].astype('int')
# imprimindo as informações da tabela atualizada
print(games_filtered.info())
<class 'pandas.DataFrame'> Index: 16444 entries, 0 to 16714 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 name 16444 non-null str 1 platform 16444 non-null str 2 year_of_release 16444 non-null int64 3 genre 16444 non-null str 4 na_sales 16444 non-null float64 5 eu_sales 16444 non-null float64 6 jp_sales 16444 non-null float64 7 other_sales 16444 non-null float64 8 critic_score 7983 non-null float64 9 user_score 9839 non-null str 10 rating 9768 non-null str dtypes: float64(5), int64(1), str(5) memory usage: 1.5 MB None
# Convertendo a coluna de object para float sem atribuir novos valores à NaN e 'tbd'
games_filtered['user_score'] = pd.to_numeric(games_filtered['user_score'], errors='coerce')
# imprimindo as informações da tabela filtrada
print(games_filtered.info())
<class 'pandas.DataFrame'> Index: 16444 entries, 0 to 16714 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 name 16444 non-null str 1 platform 16444 non-null str 2 year_of_release 16444 non-null int64 3 genre 16444 non-null str 4 na_sales 16444 non-null float64 5 eu_sales 16444 non-null float64 6 jp_sales 16444 non-null float64 7 other_sales 16444 non-null float64 8 critic_score 7983 non-null float64 9 user_score 7463 non-null float64 10 rating 9768 non-null str dtypes: float64(6), int64(1), str(4) memory usage: 1.5 MB None
# Calculando o total de vendas para os jogos e atribuindo a uma nova coluna
# criando a coluna "global_sales" e atribuindo a soma das vendas de cada região
games_filtered['global_sales'] = games_filtered['na_sales'] + games_filtered['eu_sales'] + games_filtered['jp_sales'] + games_filtered['other_sales']
# imprimindo primeiras 5 linhas danova coluna "global_sales"
games_filtered['global_sales'].head()
0 82.54 1 40.24 2 35.52 3 32.77 4 31.38 Name: global_sales, dtype: float64
Parte 2 - Análise exploratória de dados (EDA):¶
# Verificando quantos jogos foram lançados por ano
# utilizando .value_counts() para contar a quantidade de jogos lançados em cada ano
# e o sort_index para ordernar em ordem crescente.
games_per_year = games_filtered['year_of_release'].value_counts().sort_index()
# imprimindo nossa variável com os valores gerados.
print(games_per_year.head())
year_of_release 1980 9 1981 46 1982 36 1983 17 1984 14 Name: count, dtype: int64
# Vendas totais por plataforma
platform_sales = games_filtered.groupby('platform')['global_sales'].sum().sort_values(ascending=False)
# media das vendas por plataforma
platform_mean = games_filtered.groupby('platform')['global_sales'].mean().sort_values(ascending=False)
# mediana das vendas por plataforma
platform_median = games_filtered.groupby('platform')['global_sales'].median().sort_values(ascending=False)
# quantidade de jogos por plataforma
platform_count = games_filtered.groupby('platform').size().sort_values(ascending=False)
# cálculo para as plataformas
platform_analysis = games_filtered.groupby('platform')['global_sales'].agg([
'sum', # Total de vendas
'mean', # Média
'median', # Mediana
'count' # Número de jogos
]).round(2)
# ordenando por vendas totais
platform_analysis = platform_analysis.sort_values('sum', ascending=False)
print(platform_analysis.head(10))
sum mean median count platform PS2 1233.56 0.58 0.23 2127 X360 961.24 0.78 0.28 1232 PS3 931.34 0.71 0.28 1306 Wii 891.18 0.69 0.19 1286 DS 802.78 0.38 0.11 2121 PS 727.58 0.61 0.26 1190 PS4 314.14 0.80 0.20 392 GBA 312.88 0.39 0.16 811 PSP 289.53 0.24 0.09 1193 3DS 257.81 0.50 0.12 512
# Filtro de plataformas com vendas totais superiores a US$ 500M
best_platform = platform_sales[platform_sales > 500.00].index
print("Plataformas com vendas > US$ 500M: {}".format(best_platform.tolist()))
Plataformas com vendas > US$ 500M: ['PS2', 'X360', 'PS3', 'Wii', 'DS', 'PS']
- Abaixo iremos analisar as vendas das plataformas agrupadas por ano de lançamento dos jogos
# Agrupando por plataforma e ano de lançamento, e somando as vendas globais
platform_evolution = games_filtered.groupby(['year_of_release', 'platform'])['global_sales'].sum()
# transformando a série em um DataFrame e preenchendo os valores ausentes com 0
sales_timeline = platform_evolution.unstack(fill_value=0)
# visualizar evolução de vendas
fig = px.bar(sales_timeline[best_platform],
title='Evolução nas vendas das Plataformas',
labels={'value': 'Vendas Globais (milhões)',
'year_of_release': 'Ano de Lançamento',
'platform': 'Plataforma'})
fig.show()
# Filtrando as plataformas que deixaram de vender ao longo dos anos
# anos escolhidos para verificação
recent_years = [2014, 2015, 2016]
# lista que irá conter os dados filtrado no laço abaixo
old_platforms = []
# ciclo para verificar as plataformas que tiveram vendas no passado, mas não tiveram vendas recentes
for platform in games_filtered['platform'].unique():
# verificando se há vendas no passado
old_sales = platform_evolution[platform_evolution.index.get_level_values('platform') == platform]
# verificar se não tem vendas recentes
recent_sales = old_sales[old_sales.index.get_level_values('year_of_release').isin(recent_years)]
# verificando a quantidade de vendas dos filtros com IF
if len(old_sales) > 0 and len(recent_sales) == 0:
# atribuindo as plataformas a lista
old_platforms.append(platform)
# imprimindo as plataformas que deixaram de ser populares
print("Plataformas que deixaram de ser populares: {} ".format(old_platforms))
Plataformas que deixaram de ser populares: ['NES', 'GB', 'DS', 'PS2', 'SNES', 'GBA', 'N64', 'PS', 'XB', '2600', 'GC', 'GEN', 'DC', 'SAT', 'SCD', 'WS', 'NG', 'TG16', '3DO', 'GG', 'PCFX']
# Selecionando algumas plataformas
selected_platforms = ['PS2', 'XB', 'PS', 'NES', 'N64']
# visualizando a evolução das vendas por plataforma ao longo do tempo
fig2 = px.line(sales_timeline[selected_platforms],
title='Evolução das Vendas por Plataforma ao Longo do Tempo',
labels={'value': 'Vendas Totais (milhões USD)', 'year_of_release': 'Ano',
'platform': 'Plataforma'},
markers=True,
line_shape='spline')
fig2.show()
# Calcular primeiro e último ano para cada plataforma
# agrupando por plataforma e calculando o primeiro e último ano de lançamento, além do total de jogos
platforms = games_filtered.groupby('platform')['year_of_release'].agg([
('first_year', 'min'),
('last_year', 'max'),
('games_total', 'count')
]).reset_index()
# calculando duração das plataformas
platforms['platform_duration'] = platforms['last_year'] - platforms['first_year']
# Imprimindo a mediana de duração das plataformas
print('===MEDIANA DE DURAÇÃO DAS PLATAFORMAS===')
# utilizando o método median() para calcular a mediana da coluna "platform_duration" e formatando a saída
print('{:.0f} anos'.format(platforms['platform_duration'].median()))
===MEDIANA DE DURAÇÃO DAS PLATAFORMAS=== 6 anos
Acima criamos gráficos com algumas plataformas com as maiores quantidade de vendas (populares) em seus anos de atividade, e também observamos a queda das mesmas em trocas geracionais, por exemplo: PS (playstation 1) para o PS2 (playstation 2). Como também encontramos a mediana geracional entre as plataformas, na qual temos uma diferença de 6 anos para uma nova plataforma surgir, e a sua antecessora começar a recuar em vendas até ser descontinuada, explicitamente quando deixam de ser lançados novos jogos para a mesma.
Portanto para a continuidade das nossas análises, escolhemos os últimos 4 anos de vendas, pois entendemos que esses anos se encontram durante as transições das antigas e novas plataformas de gigantes da tecnologia, como Nintendo, Microsoft e Sony.
# Filtrar dados para o período escolhido
recent_data = games_filtered[games_filtered['year_of_release'].isin([2013, 2014, 2015, 2016])]
# filtrando plaformas com mais de 1 milhão em vendas no mercado global
recent_data_1 = recent_data[recent_data['global_sales'] > 1.0]
# agrupando os dados
new_platforms = recent_data_1.groupby(['year_of_release', 'platform'])['global_sales'].sum()
# transformando os dados em uma tabela pivô
recent_sales = new_platforms.unstack(fill_value=0)
# criando gráfico de barras para melhor visualizar
fig3 = px.bar(recent_sales,
title='Evolução nas vendas das Plataformas (2013-2016)',
labels={'value': 'Vendas Globais (milhões USD)',
'year_of_release': 'Ano de Lançamento',
'platform': 'Plataforma'},
barmode='group')
fig3.show()
Acima visualizamos o últimos 4 anos de vendas das plataformas que obtiveram mais de 1 milhão em vendas globais.
Em 2013 as vendas são lideradas pelo PS3, Xbox 360 e 3DS. Ainda em 2013, observamos o lançamento de novas plataformas, como PS4, Xbox One, WiiU. Em 2014 há inversão no total de vendas de duas plataformas, PS3 e X360 com PS4 e XOne, sendo as duas últimas a nova geração que vieram para substituir seus antecessores.
Entre 2013 e 2016 tivemos uma queda gradativa nas vendas do 3DS.
Em 2016, temos 4 plataformas que ultrapassaram 1 milhão em vendas. E comparado aos anos anteriores, observamos grande queda nas vendas de todas as plaformas.
# Selecionando as plataformas desejadas
potencial_sales = recent_sales[['3DS', 'PC', 'PS4', 'WiiU', 'XOne']]
# calculando variância e desvio padrão
variance_sales = potencial_sales.var()
desvio_sales = potencial_sales.std()
# imprimindo análise de variabilidade das plataformas
print("=== ANÁLISE DE VARIABILIDADE DAS PLATAFORMAS (2013-2016) ===")
print("Número de anos analisados: {}".format(len(potencial_sales)))
print("Plataformas analisadas: {}".format(list(potencial_sales.columns)))
# imprimindo a variância para cada plataforma
print("\n=== VARIÂNCIA ===")
for platform, var in variance_sales.items():
print(f"{platform}: {var:.2f}")
# imprimindo o desvio padrão para cada plataforma
print("\n=== DESVIO PADRÃO ===")
for platform, std in desvio_sales.items():
print(f"{platform}: {std:.2f}")
=== ANÁLISE DE VARIABILIDADE DAS PLATAFORMAS (2013-2016) === Número de anos analisados: 4 Plataformas analisadas: ['3DS', 'PC', 'PS4', 'WiiU', 'XOne'] === VARIÂNCIA === 3DS: 254.23 PC: 4.25 PS4: 1066.77 WiiU: 34.60 XOne: 263.22 === DESVIO PADRÃO === 3DS: 15.94 PC: 2.06 PS4: 32.66 WiiU: 5.88 XOne: 16.22
# Coeficiente de variação para comparar consistência
cv_sales = (desvio_sales / potencial_sales.mean()) * 100
print("\n=== COEFICIENTE DE VARIAÇÃO (%) ===")
print("(Menor valor = maior consistência)")
print(cv_sales.sort_values())
print()
# imprimindo os dados estatísticos com o método .describe()
print('=== Imprimindo os dados estatísticos ===')
print(potencial_sales.describe().round(2))
=== COEFICIENTE DE VARIAÇÃO (%) === (Menor valor = maior consistência) platform PS4 53.629159 XOne 56.480796 WiiU 57.666452 3DS 64.325335 PC 74.045789 dtype: float64 === Imprimindo os dados estatísticos === platform 3DS PC PS4 WiiU XOne count 4.00 4.00 4.00 4.00 4.00 mean 24.79 2.78 60.90 10.20 28.72 std 15.94 2.06 32.66 5.88 16.22 min 8.47 0.00 22.74 2.04 14.55 25% 13.39 1.84 39.53 8.41 15.06 50% 23.66 3.34 64.24 11.42 27.17 75% 35.06 4.29 85.62 13.22 40.84 max 43.36 4.45 92.38 15.91 46.01
# Criando um boxplot para vendas globais das plataformas
fig4 = px.box(potencial_sales,
title='Vendas Globais por Plataforma (2013-2016)',
labels={'value': 'Vendas Globais (milhões USD)', 'variable': 'Plataforma',
'platform': 'Plataformas'})
fig4.show()
No boxplot criado acima, observamos os últimos 4 anos de vendas das 5 plataformas com potencial de crescimento para 2017.
Estes são o 3DS e PC por terem uma duração maior, o 3DS vem recebendo novas versões ao longo dos anos e mantendo médias altas de vendas no segmento de handheld, e o PC por ser de plataforma aberta e versátil, assim entregando consistência em suas vendas no passar dos anos.
O PS4, XOne e WiiU por serem a nova geração de consoles das maiores desenvolvedoras, e estarem no inicio da sua vida geracional.
A diferença nas vendas entre as 5 plataformas em questão são significativas, com o PS4 alcançando máximas maiores, mantendo uma média de venda nos 4 anos de 60 milhões, sendo acompanhado pelo XOne e 3DS com médias e máximas bem próximas na casa dos 24 - 28 milhões na média e 43 - 46 milhões nas máximas.
# Filtrando os dados para a plataforma PS4
ps4 = recent_data[recent_data['platform'] == 'PS4']
# Criando gráfico de dispersão interativo
top_30_ps4 = ps4.nlargest(30, 'global_sales')
fig = px.scatter(top_30_ps4, x='global_sales', y='name',
title='Top 30 Jogos PS4 - Vendas Globais',
labels={'global_sales':'Vendas Globais (milhões USD)', 'name':'Jogos'},
hover_data=['user_score', 'critic_score'])
fig.update_layout(
width=1000,
height=900,
font=dict(size=12)
)
fig.show()
# calculando a correlação na tabela da plataforma PS4
ps4_corr = ps4.corr(numeric_only=True)
# exibindo a matriz de correlação
print('=== Matriz de Correlação para PS4 ===')
ps4_corr
=== Matriz de Correlação para PS4 ===
| year_of_release | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | global_sales | |
|---|---|---|---|---|---|---|---|---|
| year_of_release | 1.000000 | -0.248961 | -0.208306 | -0.060993 | -0.234796 | -0.021142 | 0.152447 | -0.235032 |
| na_sales | -0.248961 | 1.000000 | 0.785362 | 0.472981 | 0.944259 | 0.415008 | -0.020933 | 0.928160 |
| eu_sales | -0.208306 | 0.785362 | 1.000000 | 0.464563 | 0.944698 | 0.346720 | -0.048925 | 0.958157 |
| jp_sales | -0.060993 | 0.472981 | 0.464563 | 1.000000 | 0.496467 | 0.322358 | 0.171332 | 0.527129 |
| other_sales | -0.234796 | 0.944259 | 0.944698 | 0.496467 | 1.000000 | 0.409191 | -0.035639 | 0.998051 |
| critic_score | -0.021142 | 0.415008 | 0.346720 | 0.322358 | 0.409191 | 1.000000 | 0.557654 | 0.406568 |
| user_score | 0.152447 | -0.020933 | -0.048925 | 0.171332 | -0.035639 | 0.557654 | 1.000000 | -0.031957 |
| global_sales | -0.235032 | 0.928160 | 0.958157 | 0.527129 | 0.998051 | 0.406568 | -0.031957 | 1.000000 |
# Analisando apenas jogos com dados de user_score
ps4_user = ps4[ps4['user_score'] != 'NaN'] # Remove valores NaN
print(f"Jogos com dados originais na coluna 'user_score': {len(ps4_user)}")
# Calcular correlação
if len(ps4_user) > 10: # Se tiver dados suficientes
corr_user = ps4_user[['user_score', 'global_sales']].corr()
print("\nCorrelação com dados originais:")
print(corr_user)
Jogos com dados originais na coluna 'user_score': 392
Correlação com dados originais:
user_score global_sales
user_score 1.000000 -0.031957
global_sales -0.031957 1.000000
# Analisando apenas jogos com dados de critic_score
ps4_critic = ps4[ps4['critic_score'] != 'NaN'] # Remove valores NaN
print(f"Jogos com dados originais 'critic_score': {len(ps4_critic)}")
# Calcular correlação
if len(ps4_critic) > 10: # Se tiver dados suficientes
corr_critic = ps4_critic[['critic_score', 'global_sales']].corr()
print("\nCorrelação com dados originais:")
print(corr_critic)
Jogos com dados originais 'critic_score': 392
Correlação com dados originais:
critic_score global_sales
critic_score 1.000000 0.406568
global_sales 0.406568 1.000000
# Gráfico de dispersão para critic_score x vendas
fig5 = px.scatter(ps4, x='critic_score', y='global_sales',
title='Relação: Nota dos Críticos vs Vendas Globais (PS4)',
labels={'critic_score':'Nota dos Críticos',
'global_sales':'Vendas Globais (milhões USD)'},
hover_data=['name'])
fig5.show()
# Gráfico de dispersão para user_score x vendas
fig6 = px.scatter(ps4, x='user_score', y='global_sales',
title='Relação: Nota dos Usuários vs Vendas Globais (PS4)',
labels={'user_score':'Nota dos Usuários',
'global_sales':'Vendas Globais (milhões USD)'},
hover_data=['name'])
fig6.show()
Cálculos de correlação
- Encontramos uma correlação positiva moderada (0.406) entre a coluna 'critic_score' e as vendas globais da plataforma PS4, indicando assim que avaliações mais altas dos profissionais críticos tendem a resultar em vendas maiores, mesmo sendo apenas uma relação moderada, ainda continua significativa.
- Em relação as avaliações dos usuários (user_score), temos uma correlação quase zero (-0.0319) com as vendas globais do PS4, indicando que essas notas não influenciam muito nas vendas.
# Comparando as vendas dos mesmos jogos em outras plataformas.
# filtrando o nome dos jogos
games_filter = ps4['name']
# filtrando a tabela pelo nome dos jogos que queremos analisar.
games_sales = recent_data[recent_data['name'].isin(games_filter)]
# filtrando plataformas diferentes do PS4
games_others_plat = games_sales[games_sales['platform'] != 'PS4']
# verificando quantos jogos do PS4 existem em outras plataformas
print(f"Jogos no PS4: {ps4['name'].nunique()}")
print(f"Jogos do PS4 encontrados em outras plataformas: {games_others_plat['name'].nunique()}")
Jogos no PS4: 392 Jogos do PS4 encontrados em outras plataformas: 316
# Criando gráfico de dispersão interativo para jogos do PS4 em outras plataformas
top_30_plat = games_others_plat.nlargest(30, 'global_sales')
fig7 = px.scatter(top_30_plat, x='global_sales', y='name',
title='Jogos em outras plataformas - Vendas Globais',
labels={'global_sales':'Vendas Globais (milhões USD)', 'name':'Jogos'},
hover_data=['user_score', 'critic_score', 'platform'])
fig7.update_layout(
width=1000,
height=900,
font=dict(size=12)
)
fig7.show()
# Jogos que encontramos na plataforma PS4 com maiores diferenças de vendas em outras plataformas
# imprimindo o título para a análise
print("Top 30 jogos com maiores vendas em outras plataformas:\n")
# utilizando o método nlargest para encontrar os 30 jogos com maiores vendas em outras plataformas
# e exibindo as colunas de interesse
top_others = games_others_plat.nlargest(30, 'global_sales')[['name', 'platform', 'global_sales']]
# imprimindo os resultados
print(top_others.head())
Top 30 jogos com maiores vendas em outras plataformas:
name platform global_sales
16 Grand Theft Auto V PS3 21.05
23 Grand Theft Auto V X360 16.27
60 Call of Duty: Ghosts X360 10.24
69 Call of Duty: Ghosts PS3 9.36
72 Minecraft X360 9.18
# Distribuição de vendas globais e regionais por gênero
# agrupando por gênero e somando as vendas globais e regionais
genre = games_filtered.groupby('genre')[['global_sales', 'na_sales', 'eu_sales', 'jp_sales', 'other_sales']].sum()
# imprimindo a distribuição de vendas por gênero
print("*** DISTRIBUIÇÃO DE VENDAS POR GÊNERO ***\n")
print(genre)
*** DISTRIBUIÇÃO DE VENDAS POR GÊNERO ***
global_sales na_sales eu_sales jp_sales other_sales
genre
Action 1716.52 863.17 510.99 160.14 182.22
Adventure 233.33 101.52 63.20 52.24 16.37
Fighting 442.66 220.51 99.00 87.28 35.87
Misc 790.29 399.57 210.60 107.02 73.10
Platform 825.55 444.44 199.39 130.71 51.01
Puzzle 239.89 121.13 49.78 56.68 12.30
Racing 723.49 356.86 234.49 56.63 75.51
Role-Playing 931.08 330.04 188.24 353.39 59.41
Shooter 1041.36 584.83 314.52 38.68 103.33
Simulation 387.96 180.40 113.35 63.64 30.57
Sports 1309.67 671.20 371.33 134.93 132.21
Strategy 172.57 67.75 44.79 49.30 10.73
# Análise mais completa das vendas globais por gênero
genre_analysis = games_filtered.groupby('genre').agg({
'global_sales': ['sum', 'mean', 'median', 'count']}).round(2)
# simplificando os nomes das colunas
genre_analysis.columns = ['total_sales', 'mean_sales', 'median_sales', 'game_count']
genre_analysis = genre_analysis.sort_values('total_sales', ascending=False)
# imprimindo a análise completa por gênero
print("*** ANÁLISE COMPLETA POR GÊNERO ***\n")
print(genre_analysis)
*** ANÁLISE COMPLETA POR GÊNERO ***
total_sales mean_sales median_sales game_count
genre
Action 1716.52 0.52 0.19 3307
Sports 1309.67 0.57 0.22 2306
Shooter 1041.36 0.80 0.24 1296
Role-Playing 931.08 0.63 0.18 1481
Platform 825.55 0.94 0.27 878
Misc 790.29 0.46 0.16 1721
Racing 723.49 0.59 0.19 1226
Fighting 442.66 0.53 0.21 837
Simulation 387.96 0.45 0.15 857
Puzzle 239.89 0.42 0.10 569
Adventure 233.33 0.18 0.05 1293
Strategy 172.57 0.26 0.10 673
# Verificando a média das notas por gênero
genre_grade = games_filtered.groupby('genre')[['user_score', 'critic_score']].mean().round(2)
# imprimindo a média das notas por gênero
print("*** NOTAS POR GÊNERO ***\n")
print(genre_grade)
*** NOTAS POR GÊNERO ***
user_score critic_score
genre
Action 7.06 66.68
Adventure 7.14 65.27
Fighting 7.30 69.16
Misc 6.81 66.65
Platform 7.31 68.12
Puzzle 7.14 67.23
Racing 7.04 68.01
Role-Playing 7.62 72.66
Shooter 7.05 70.26
Simulation 7.13 68.61
Sports 6.95 71.99
Strategy 7.29 72.16
Seguindo o enunciado, encontramos os 3 maiores gêneros em vendas: Action, Sports, Shooter
E os 3 menos vendidos: Puzzle, adventure e strategy
Os dois primeiros gêneros mais vendidos possuem uma grande contagem de jogos, isso influência em uma quantidade maior de receita em vendas. Mas também sabemos que esses dois primeiros jogos atraem mais compradores por serem jogos que exploram o instinto humano de competição e curiosidade. Os jogos de gênero shooter entregam adrenalina e desafio em sobreviver em uma missão perigosa como em call of duty e battlefield.
Com isso as vendas de cada gênero irá depender do gosto do usuário e também da qualidade do título lançado, pois jogos bem produzidos acabam por receber notas boas e assim despertam interesse em usuários que normalmente não comprariam.
Em relação aos 3 gêneros menos vendidos citados acima, as vendas deles estão estritamente ligadas a baixa procura, sendo assim gêneros nichados, pois mesmo com média de notas criticas e de usuários em bons números, observamos que as vendas não atingem altos valores, como também não encontramos diferenças nas vendas por região para tais gêneros.
Parte 3 - Criação de Perfis de Utilizador por Região:¶
# Função criada para separar cada região unicamente e exibir o resultado desejado.
def perfil_regiao(regiao):
# 5 plataformas principais
plat_sales = recent_data.groupby('platform')[regiao].sum().sort_values(ascending=False).head(5)
# 5 principais gêneros
genre_sales = recent_data.groupby('genre')[regiao].sum().sort_values(ascending=False).head(5)
# vendas por Rating
rating_sales = recent_data.groupby('rating')[regiao].sum().sort_values(ascending=False)
# criando DataFrames organizados
plat_df = pd.DataFrame({
'Plataforma': plat_sales.index,
'Vendas (milhões)': plat_sales.values
}).reset_index(drop=True)
genre_df = pd.DataFrame({
'Gênero': genre_sales.index,
'Vendas (milhões)': genre_sales.values
}).reset_index(drop=True)
rating_df = pd.DataFrame({
'Rating': rating_sales.index,
'Vendas (milhões)': rating_sales.values
}).reset_index(drop=True)
return {
'plataformas': plat_df,
'generos': genre_df,
'ratings': rating_df
}
# Chamando a função para região NA
perfil_na = perfil_regiao('na_sales')
# Exibindo o perfil de usuário para a região NA
print("=== PERFIL DE USUÁRIO - AMÉRICA DO NORTE ===\n")
print(" TOP 5 PLATAFORMAS:")
print(perfil_na['plataformas'])
print("\n TOP 5 GÊNEROS:")
print(perfil_na['generos'])
print("\n VENDAS POR RATING:")
print(perfil_na['ratings'])
=== PERFIL DE USUÁRIO - AMÉRICA DO NORTE ===
TOP 5 PLATAFORMAS:
Plataforma Vendas (milhões)
0 PS4 108.74
1 XOne 93.12
2 X360 81.66
3 PS3 63.50
4 3DS 38.20
TOP 5 GÊNEROS:
Gênero Vendas (milhões)
0 Action 126.05
1 Shooter 109.74
2 Sports 65.27
3 Role-Playing 46.40
4 Misc 27.49
VENDAS POR RATING:
Rating Vendas (milhões)
0 M 165.21
1 E 79.05
2 E10+ 54.24
3 T 49.79
# Chamando a função para região EU
perfil_eu = perfil_regiao('eu_sales')
# Exibindo o perfil de usuário para a região EU
print("=== PERFIL DE USUÁRIO - EUROPA ===\n")
print(" TOP 5 PLATAFORMAS:")
print(perfil_eu['plataformas'])
print("\n TOP 5 GÊNEROS:")
print(perfil_eu['generos'])
print("\n VENDAS POR RATING:")
print(perfil_eu['ratings'])
=== PERFIL DE USUÁRIO - EUROPA ===
TOP 5 PLATAFORMAS:
Plataforma Vendas (milhões)
0 PS4 141.09
1 PS3 67.81
2 XOne 51.59
3 X360 42.52
4 3DS 30.96
TOP 5 GÊNEROS:
Gênero Vendas (milhões)
0 Action 118.13
1 Shooter 87.86
2 Sports 60.52
3 Role-Playing 36.97
4 Racing 20.19
VENDAS POR RATING:
Rating Vendas (milhões)
0 M 145.32
1 E 83.36
2 E10+ 42.69
3 T 41.95
# Chamando a função para região JP
perfil_jp = perfil_regiao('jp_sales')
# Exibindo o perfil de usuário para a região JP
print("=== PERFIL DE USUÁRIO - JAPÃO ===\n")
print(" TOP 5 PLATAFORMAS:")
print(perfil_jp['plataformas'])
print("\n TOP 5 GÊNEROS:")
print(perfil_jp['generos'])
print("\n VENDAS POR RATING:")
print(perfil_jp['ratings'])
=== PERFIL DE USUÁRIO - JAPÃO ===
TOP 5 PLATAFORMAS:
Plataforma Vendas (milhões)
0 3DS 67.81
1 PS3 23.35
2 PSV 18.59
3 PS4 15.96
4 WiiU 10.88
TOP 5 GÊNEROS:
Gênero Vendas (milhões)
0 Role-Playing 51.04
1 Action 40.49
2 Misc 9.20
3 Fighting 7.65
4 Shooter 6.61
VENDAS POR RATING:
Rating Vendas (milhões)
0 T 20.59
1 E 15.14
2 M 14.11
3 E10+ 5.89
Acima criamos uma função para filtrar separadamente as regiões e as mostramos em formato de tabela para melhor visualização entre plataformas, generos, ratings e seus valores de vendas.
- Nos mercados da América do Norte e Europa encontramos um padrão em relação aos pontos analisados, apenas havendo uma única diferença no quinto gênero mais vendido nos dois mercados, onde na América temos o gênero misc e na Europa o gênero racing.
- Já no mercado Japonês vemos uma maior diferença, possivelmente ligado a cultura e costumes regionais, onde observamos a preferência dos usuários por plataformas handheld (3DS e PSV), jogos do genero RPG (Role-Playing). E apenas no caso do japão, as vendas parecem ser afetadas pelo rating, já que as maiores vendas relatadas somam 20 milhões com rating T (teen) e 15 milhões (everyone), mas isso possivelmente está ligado aos valores ausentes que encontramos na coluna 'rating' do nosso dataset original.
Parte 4 - Teste de Hipóteses Estatísticas:¶
PRIMEIRO CENÁRIO - As hipóteses escolhidas são:
- Hipótese nula: As classificações médias dos usuários das plataformas Xbox One e PC são as mesmas.
- Hipótese alternativa: As classificações médias dos usuários das plataformas Xbox One e PC são as diferentes.
Escolhemos o teste estatístico da Hipótese sobre a igualdade das médias de duas populações.
Nosso valor alpha será: 5% ou 0.05
# Testando as hipóteses do primeiro cenário
xbox_one = recent_data[recent_data['platform'] == 'XOne']
pc = recent_data[recent_data['platform'] == 'PC']
# filtrando apenas valores válidos (não NaN)
xbox_scores = xbox_one['user_score'].dropna().values
pc_scores = pc['user_score'].dropna().values
# realizando teste T
results = st.ttest_ind(xbox_scores, pc_scores)
alpha = 0.05
# imprimindo os resultados do teste do primeiro cenário
print('*** TESTE DE HIPÓTESE DO PRIMEIRO CENÁRIO ***')
print('p-value: ', results.pvalue)
# interpretando os resultados do teste
if (results.pvalue < alpha):
print('\nRejeitamos a hipótese nula')
print('As médias são DIFERENTES')
else:
print('\nNão podemos rejeitar a hipótese nula')
print('Não há evidência de diferença significativa')
*** TESTE DE HIPÓTESE DO PRIMEIRO CENÁRIO *** p-value: 0.14012658403611647 Não podemos rejeitar a hipótese nula Não há evidência de diferença significativa
SEGUNDO CENÁRIO - As hipóteses escolhidas são:
- Hipótese nula: As classificações médias de usuários para os gêneros Action (ação) e Sports (esportes) são as mesmas.
- Hipótese alternativa: As classificações médias de usuários para os gêneros Action (ação) e Sports (esportes) são diferentes.
Escolhemos o teste estatístico da Hipótese sobre a igualdade das médias de duas populações.
Nosso valor alpha será: 5% ou 0.05
# Testando as hipóteses do segundo cenário
action = recent_data[recent_data['genre'] == 'Action']
sports = recent_data[recent_data['genre'] == 'Sports']
# filtrando apenas valores válidos (não NaN)
action_score = action['user_score'].dropna().values
sports_score = sports['user_score'].dropna().values
# realizando teste T
results = st.ttest_ind(action_score, sports_score)
alpha = 0.05
# imprimindo os resultados do segundo cenário
print('*** TESTE DE HIPÓTESE SEGUNDO CENÁRIO ***')
print('p-value: ', results.pvalue)
# interpretando os resultados do teste
if (results.pvalue < alpha):
print('\nRejeitamos a hipótese nula')
print('As médias são DIFERENTES')
else:
print('\nNão podemos rejeitar a hipótese nula')
print('Não há evidência de diferença significativa')
*** TESTE DE HIPÓTESE SEGUNDO CENÁRIO *** p-value: 1.0517832389140034e-27 Rejeitamos a hipótese nula As médias são DIFERENTES
Parte 6 - Conclusão Geral¶
Chegamos a conclusão deste projeto. Estarei explicando e também listando os pontos abordados, como foram tratados os dados e as decisões tomadas que nos guiaram até o fim deste projeto.
- Iniciamos realizando toda a preparação dos dados, fazendo correções e alterações na tabela principal que achamos necessárias para obter uma análise mais limpa e bem organizada. Logo também realizamos diversas filtragens para abranger todos os nossos temas abordados e favorecer nosso processo de análise das vendas, comportamentos e finalização do projeto.
- Com isso nossas análises indicaram como já citado anteriormente durante o projeto, que novas plataformas possuem uma janela de lançamento de em média 6 anos em relação a sua plataforma antecessora, esse padrão de lançamento é facilmente percebido nas plataformas da Sony, Microsoft e Nintendo. Essas empresas lideram o mercado, com as maiores vendas registradas sendo da Sony, com o console PS2 que ultrapassou a marca dos U$1.2 bilhões de dólares, e cerca de 2127 jogos. Mas ao longo dos anos, como informado são lançados novos consoles, plataformas. Portanto nossas análises se dirigem aos últimos 4 anos de vendas da ICE Store, onde nos deparamos com uma troca geracional de plataformas, analisando os anos entre 2013 e 2016 encontramos vendas que inicialmente eram lideradas pelo PS3 e durante a troca geracional pudemos observar a queda dessas vendas e sendo assumidas pelo seu sucessor, o PS4. O mesmo acontecimento é observado para as plataformas da Microsoft (Xbox) e Nintendo (Wii), mas na Nintendo vemos uma queda gradual nas vendas do seu handheld (3DS).
- No ano de 2016, observamos uma queda bastante perceptível nas vendas em todas as plataformas, essas quedas podem estar relacionadas aos dados recebidos para análise, já que recebemos uma notificação de que os dados para este ano de 2016 podem estar incompletos. Mesmo assim decidimos por manter esse ano (2016) em nossa abordagem, pois conseguimos observar a dominância nas vendas das plataformas mais recentes, já que as mesma estão no início da sua vida útil. Sendo essas as plataformas com maior potencial em vendas: 3DS, PS4, WiiU, Xbox One e PC, sendo a última plataforma citada a única a não atingir mais de 1 milhão em vendas em 2016, mas sendo um pilar importante pois é a única plataforma aberta, e com maior longevidade entre as demais. Assim a diferença nas vendas entre as 5 plataformas em questão são significativas, com o PS4 alcançando 92 milhões de máxima e mantendo uma média de venda nos 4 anos de 60 milhões, sendo acompanhado pelo XOne e 3DS com médias e máximas bem próximas na casa dos 24 - 28 milhões na média e 43 - 46 milhões nas máximas.
- Nas análises de gênero e plataformas por região, como já citado, observamos padrões nos resultados, possivelmente ligados a cultura e costumes locais. Esses resultados podem ajudar a ICE Store a criar campanhas promocionais regionais, assim direcionando corretamente marketings para esses públicos com perfis traçados, possibilitando o aumento das vendas para cada região.
- Por fim, ao realizar nossos testes de hipótese, nos deparamos com o primeiro cenário de que as classificações médias dos usuários das plataformas Xbox One e PC são as mesmas, não havendo base estatística suficiente para afirmar que exista diferenças. Entretanto em nosso segundo cenário de hipótese observamos que existe diferenças estatísticas nas avaliações médias dos usuários para os gêneros Action e Sports, com a média do genêro action maior que o gênero sports, com o gênero action possuindo cerca de mil jogos a mais lançados e sendo também o gênero mais vendido.